package com.chandon.juc.threadPool;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 定时任务线程池
 * public static ScheduledExecutorService newScheduledThreadPool(
 *      int corePoolSize, ThreadFactory threadFactory) {
 *      return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
 * }
 *
 *              |
 *              |
 *
 * public ScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory) {
 *      super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
 *      new DelayedWorkQueue(), threadFactory);
 * }
 *
 *
 * public class ScheduledThreadPoolExecuto  extends ThreadPoolExecutor  implements ScheduledExecutorService
 *
 *
 * 本质上还是线程池，延时功能基于DelayedWorkQueue，周期性任务执行完毕后，再次将任务扔回阻塞队列。
 * 可正常执行，也可定时执行
 *
 * @author Chandon
 */

public class TestScheduleThreadPool {
	public static void main(String[] args) {



		ScheduledExecutorService scheduledThreadPool =
				Executors.newScheduledThreadPool(4, new NamedThreadFactory("scheduledThreadFactory"));


		testExecute(scheduledThreadPool);


		testSchedule(scheduledThreadPool);


		testScheduleWithFixedDelay(scheduledThreadPool);


		testScheduleAtFixedRate(scheduledThreadPool);
	}

	private static void testExecute(ScheduledExecutorService scheduledThreadPool) {
		/* 普通执行，与普通线程池没有区别 */

		scheduledThreadPool.execute(() -> System.out.println(Thread.currentThread().getName() + " 任务1"));
		scheduledThreadPool.execute(() -> System.out.println(Thread.currentThread().getName() + " 任务2"));
		scheduledThreadPool.execute(() -> System.out.println(Thread.currentThread().getName() + " 任务3"));
	}

	private static void testSchedule(ScheduledExecutorService scheduledThreadPool) {
		/* 指定延迟时间执行 */

		scheduledThreadPool.schedule(() -> {
			System.out.println(Thread.currentThread().getName() + " 任务4");
		}, 5, TimeUnit.SECONDS);
	}


	/* 周期执行任务，与任务执行时间无关 */


	private static void testScheduleWithFixedDelay(ScheduledExecutorService scheduledThreadPool) {
    /*
	    周期执行
	    第一次延迟执行，后周期执行
        第一次执行延迟2秒，以后每隔5秒执行一次
        任务周期从任务执行结束才开始计算
     */
		scheduledThreadPool.scheduleWithFixedDelay(() -> {
			System.out.println(Thread.currentThread().getName() + " 任务5");

		}, 2, 5, TimeUnit.SECONDS);
	}

	private static void testScheduleAtFixedRate(ScheduledExecutorService scheduledThreadPool) {
    /*
      周期执行
      第一次执行延迟2秒，以后每隔4秒执行一次
      任务周期从任务执行开始便开始计算
     */
		scheduledThreadPool.scheduleAtFixedRate(() -> {
			System.out.println(Thread.currentThread().getName() + " 任务6");
		}, 1, 4, TimeUnit.SECONDS);
	}

}
